
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.bluetooth.BluetoothStateException;
import javax.bluetooth.RemoteDevice;
import javax.microedition.io.StreamConnection;
import javax.swing.JLabel;

class USer extends Thread {

    private StreamConnection con = null;
    private DataInputStream in = null;
    private DataOutputStream out = null;
    private UserTable perUser = null;
    private RemoteDevice remote = null;
    private String name = null;
    private Connection dbcon = null;
    private Events listener = null;
    private String datain = null;
    private DateFormat date1 = new SimpleDateFormat("dd-MM-yyyy");
    private Date date2 = new Date();
    String items = null,timed="",am_pm="",newline="" ;
    int ordersMade = 0,amounpaid,bal;
    Statement stmt;
    ResultSet rs;
    private boolean isRunning = true;
    int OrderP = 0, IncomingOrders, price;
    private Vector OrderVector = new Vector();
    private String kitchenString = null, CustName = null, CustId = null,
            RecieptNo = null, CustTable = null, datee = null,
            ordere = null, cashier = null, orderID = null;
    private static final int Num_Chars = 5;
    private static String chars = "ABCDE01234";
    private static Random r = new Random();
    private StringBuffer orderlist= new StringBuffer();

    
    public USer(Events l, Connection c, StreamConnection cd, UserTable pUser) {
        this.listener = l;
        this.dbcon = c;
        this.con = cd;
        this.perUser = pUser;
        this.start();
    }

    @Override
    public void run() {

        while (true) {
            try {
                in = new DataInputStream(con.openDataInputStream());
                out = con.openDataOutputStream();

            } catch (IOException ex) {
            }

            try {

                remote = RemoteDevice.getRemoteDevice(con);
                name = remote.getFriendlyName(true);
                listener.PostMsg(name + " Connected.");
                if(name.equals(listener.KitchenName())){
                    listener.kitchenOn("yes");
                }
                if(name.equals(listener.PointOfSale())){
                    listener.POSOn("yes");
                }

            } catch (IOException ex) {
            }

            //add and delete  clients.
            perUser.add(name, this);
            perUser.DuserDeleted(name);

            //list the No of Clients On and Off.
            listofclients();
            listofclientsoff();

            listener.NoofClient(perUser.clientsOn());
            listener.NoofClientOff(perUser.clientsOff());


            //*********Start the Recieving Thread*****//
            for (;;) {
                try {
                    if (isRunning) {
                        datain = in.readUTF();
                        recieve(datain);
                    }
                } catch (IOException ex) {
                }
            }

        }
    }

    private void close() {

        perUser.delete(name);
        perUser.AddusrDeleted(name, this);

        listofclients();
        listofclientsoff();

        listener.NoofClient(perUser.clientsOn());
        listener.NoofClientOff(perUser.clientsOff());

        datain = null;

        out = null;
        in = null;
        con = null;
        dbcon = null;
        isRunning = false;
        listener.PostMsg(name + " closed");

       if(name.equals(listener.KitchenName())){
           listener.kitchenOn("no");
            }
       if(name.equals(listener.PointOfSale())){
           listener.POSOn("no" );
          }

    }

    synchronized void recieve(String str) {

        if (str.equals("exit")) {
            close();

        } else if (str.equals("food")) {
            OrderRcvd("food");


        } else if (str.equals("drinks")) {
            OrderRcvd("drinks");

        } else if (str.equals("snacks")) {
            OrderRcvd("snacks");

        } else if (str.equals("services")) {
            OrderRcvd("services");

        } else if (str.equals("C-Conn")) {
            try {
                out.writeUTF("No. of Clients Conneceted: " + perUser.clientsOn());
                out.flush();
                out.writeUTF("No. of Clients Disconnected: " + perUser.clientsOff());
                out.flush();
            } catch (IOException ex) {
            }

        } else if (str.equals("C-Orders")) {
            try {

                out.writeUTF("No. of Placed Orders: " + ordersMade);
                out.flush();
            } catch (IOException ex) {
            }

        } else if (str.equals("DB-Conn")) {
            if (dbcon != null) {
                try {
                    out.writeUTF("Database Connected.");
                    out.flush();
                } catch (IOException ex) {
                }
            } else {
                try {
                    out.writeUTF("Database Disconnected.");
                    out.flush();
                } catch (IOException ex) {
                }

            }
        } else if (str.equals("P-Orders")) {
            try {
                out.writeUTF("No. of Processed Orders: " + OrderP);
                out.flush();
            } catch (IOException ex) {
            }

        } else {
            process(str);

        }
    }

    synchronized public void OrderRcvd(String str) {
        listener.PostMsg("Data from " + name + ": " + str);
        try {
            stmt = dbcon.createStatement();
            rs = stmt.executeQuery("Select * from " + str);

            if (rs.wasNull()) {
                datain = null;

            } else {
                listener.PostMsg(name + " Replied. Recieved :");
                listener.PostMsg("---------------------------------------");
                while (rs.next()) {
                    try {
                        out.writeUTF(rs.getString("Name") + "   :" + rs.getString("Price"));
                        listener.PostMsg("     " + rs.getString("Name") + "   :" + rs.getString("Price"));
                        out.flush();
                    } catch (IOException ex) {
                    }
                }
                listener.PostMsg("---------------------------------------");
                datain = null;

            }
        } catch (SQLException ex) {
        }

    }

    synchronized public void process(String s) {

        if (name.equals(listener.KitchenName().toString())) {
        if(s.startsWith("!" )){
             try {
                                   USer u = perUser.get(listener.KitchenName().toString());
                    String usern="",pw="",usern1="",pw1="",fname="" ;
                   pw =s.substring(s.indexOf("!")+1, s.indexOf("£")-1).trim();
                    usern=s.substring(s.indexOf("£")+1, s.length()).trim();
                    //select from database

                  //  System.out.println("hh" );
                    stmt = dbcon.createStatement();
                    rs = stmt.executeQuery("Select * from workers where Responsibility= 'Chef' and Username= '"+usern+"'and pwd='"+pw+"'");
                    //System.out.println(usern+" - "+pw );

                    while(rs.next()){
                        fname=rs.getString("Fname" );
                      usern1=rs.getString("Username" );
                      pw1=rs.getString("pwd" );
                      }
                   //     System.out.println(usern1+" - "+pw1 );
                   if(usern1.equals("" ) || pw1.equals("" ) ){
                        try {
                            u.out.writeUTF("No");
                            out.flush();
                        } catch (IOException ex) {}
                    }else{
                      try {
                            u.out.writeUTF("+ "+fname);
                            out.flush();
                            u=null;
                        } catch (IOException ex) {}

                    }

                } catch (SQLException ex) { }

        }else{
         /**************Data Sent from Kitchen*******/
            CustId = s.substring(0, s.indexOf("!") - 1).trim();
            CustTable = s.substring(s.indexOf("!") + 1, s.indexOf("?") - 1).trim();
            ordere= s.substring(s.indexOf("?") + 1, s.indexOf("$") - 1).trim();
            price= Integer.parseInt(s.substring(s.indexOf("$") + 1, s.indexOf("*") - 1).trim());
            timed = s.substring(s.indexOf("*") + 1, s.indexOf("%") - 1).trim();
            RecieptNo = s.substring(s.indexOf("%") + 1, s.length()).trim();

            try {
                //-----------Insert the placed orders to the database------------
                stmt = dbcon.createStatement();
                stmt.executeUpdate("INSERT INTO processedorder VALUES(null,'" + CustId + "','" + CustTable + "'," +
                "'" + ordere + "','" + price + "','" + date1.format(date2) + "', '"+timed+" ','"+RecieptNo + "' )");

            } catch (SQLException ex) {}
              //----------------------------------------------------------------------

                OrderP++;

                //Display the Processed order onto the screen//
                listener.ProcessedOrderMade("-----------------------------------------------------------------");
                listener.ProcessedOrderMade(OrderP + "). Order from table: "+CustTable+" | CustID: "+CustId);
                listener.ProcessedOrderMade("" + ordere);
                listener.ProcessedOrderMade("RcptNo: " + RecieptNo);
                listener.ProcessedOrderMade("Price : " + price);
                listener.ProcessedOrderMade("-----------------------------------------------------------------");
                listener.TotalNoOrderMade(OrderP);

                //Release Resources//
                CustId = null;
                timed = null;
                CustTable = null;
                ordere = null;
                price = 0;
                RecieptNo = null;
                datee = null;


        }
           
          
        } else if (name.equals(listener.PointOfSale().toString())) {
            USer u = perUser.get(listener.PointOfSale().toString());
          if(s.startsWith("!" )){
            try {
                   String usern="",pw="",usern1="",pw1="",fname="" ;
                   pw =s.substring(s.indexOf("!")+1, s.indexOf("@")-1).trim();
                    usern=s.substring(s.indexOf("@")+1, s.length()).trim();
                    //select from database

                  //  System.out.println("hh" );
                    stmt = dbcon.createStatement();
                    rs = stmt.executeQuery("Select * from workers where Responsibility= 'Cashier' and Username= '"+usern+"'and pwd='"+pw+"'");

                    while(rs.next()){
                        fname=rs.getString("Fname" );
                      usern1=rs.getString("Username" );
                      pw1=rs.getString("pwd" );
                      }
                   //     System.out.println(usern1+" - "+pw1 );
                   if(usern1.equals("" ) || pw1.equals("" ) ){
                        try {
                            u.out.writeUTF("No");
                            out.flush();
                        } catch (IOException ex) {}
                    }else{
                      try {
                            u.out.writeUTF("+ "+fname);
                            out.flush();
                            u=null;
                        } catch (IOException ex) {}

                    }

                } catch (SQLException ex) { }

          }else{
           if (s.startsWith("*")) {
                   
                        //--------------Get the Unque id from pos----------------
                try {
                       stmt = dbcon.createStatement();
                        rs = stmt.executeQuery("select * from paidorder where orderID='" + s.substring(s.indexOf("*") + 1, s.length()).trim() + "'");
                         String cuid = "", time ="", tabled = "", orderd = "", priced = "", dated = "", rect = "";
                         while (rs.next()) {
                       cuid = rs.getString(2);

                         }
                         if(cuid.equals("")){
                         rs = stmt.executeQuery("select * from processedorder where orderID='" + s.substring(s.indexOf("*") + 1, s.length()).trim() + "'");
                        while (rs.next()) {
                        cuid = rs.getString(2);
                        tabled = rs.getString(3);
                        orderd= rs.getString(4);
                        priced = rs.getString(5);
                        dated = rs.getString(6);
                        time = rs.getString(7);
                        rect = rs.getString(8);
                       }
                         if(cuid.equals("" ) || orderd.equals("" )){
                                    try {
                                        u.out.writeUTF("NoRcd");
                                        out.flush();
                                    } catch (IOException ex) {}
                         }else{
                                    try {
                 u.out.writeUTF(cuid + " ! " + tabled + " @ " + orderd + " # " + priced + " $ " +dated + " % " +time  + " ^ " +rect );
                 out.flush();
                                    } catch (IOException ex) {  }

                         }
                         }else{
                            try {
                                u.out.writeUTF("DD");
                                out.flush();
                            } catch (IOException ex) { }
                         }
                         } catch (SQLException ex) { }
              } else {
                /*******************Data Sent from POS *********/
                CustId = s.substring(0, s.indexOf("!") - 1);
                CustTable = s.substring(s.indexOf("!") + 1, s.indexOf("?") - 1);
                ordere = s.substring(s.indexOf("?") + 1, s.indexOf("$") - 1);
                price = Integer.parseInt(s.substring(s.indexOf("$") + 1, s.indexOf("*") - 1).trim());
                RecieptNo = s.substring(s.indexOf("*") + 1, s.indexOf("%") - 1);
                timed = s.substring(s.indexOf("%") + 1, s.indexOf("^") - 1);
                cashier = s.substring(s.indexOf("#") + 1, s.indexOf("(")-1);
                amounpaid=Integer.parseInt((s.substring(s.indexOf("(") + 1, s.indexOf("/" )-1)).trim());
                datee=s.substring(s.indexOf("/" )+1 , s.length());
                bal = amounpaid-price;
                try {


                    //save paid orders into table paidorders
                    stmt = dbcon.createStatement();
                    stmt.executeUpdate("INSERT INTO paidorder VALUES(null,'" + CustId + "','" + CustTable + "'," +
                    "'" + ordere + "','" + price + "','" + date1.format(date2) + "','"+timed+"', '"+ RecieptNo +
                    "', '"+amounpaid+"', '"+bal+"','" + cashier + " '  )");

                    //**************************************************//
                } catch (SQLException ex) {
                }

                //**************************************************//

            }


          }
           


        }else if(s.startsWith("%" )){
        CustTable=s.substring(s.indexOf("%" )+1 , s.length());
        }
        else {
            if (!s.startsWith("TOTAL")) {
                OrderVector.addElement(s);
              orderlist.append(newline).append(s);
               newline="\n";
            } else {
                String P = s.substring(s.indexOf(":") + 1, s.length());
              if (perUser.KitchenOn(listener.KitchenName().toString()) == true) {
                    USer k = perUser.get(listener.KitchenName().toString().trim());
                     System.out.println(k);
                    orderID = unID();
                    listener.OrderMade("Order ID:" + orderID + "     from table: " + CustTable + " Contains: ");
                    for (int i = 0; i < OrderVector.size(); i++) {
                        try {
                            k.out.writeUTF(""+ OrderVector.elementAt(i).toString());
                            out.flush();
                        } catch (IOException ex) {
                          Logger.getLogger(USer.class.getName()).log(Level.SEVERE, null, ex);
                       }

                        listener.OrderMade("            " + OrderVector.elementAt(i));
                    }
                    listener.OrderMade("                 ----------------");
                   

                    listener.OrderMade("  Total Price: " + P);
                    try {
                        k.out.writeUTF("Q" + "? " + P + " * " + CustTable + " / " + orderID);
                        out.flush();
                        System.out.println("out 2");
                    } catch (IOException ex) {Logger.getLogger(USer.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    listener.OrderMade("                 ----------------");
                    listener.OrderMade("__________________________________________________________________");

                        Calendar calender = new GregorianCalendar();
                      if(calender.get(Calendar.AM_PM)==0){
                   am_pm="AM";
                  }else{
                  am_pm="PM";
                   }
               timed=""+calender.get(Calendar.HOUR_OF_DAY)+":"+calender.get(Calendar.MINUTE)+" "+am_pm;
                    try {
//" + + "
                        //  try {
                        stmt = dbcon.createStatement();
                        stmt.executeUpdate("INSERT INTO placedorder VALUES(null,'" + orderID + "','" + CustTable + "', '" +orderlist.substring(0, orderlist.length()-1).toString()+"',  '"+ Integer.parseInt(P.trim()) + "','" + date1.format(date2) + "','"+timed+"')");

                    } catch (SQLException ex) {
                        Logger.getLogger(USer.class.getName()).log(Level.SEVERE, null, ex);
                    }
              // System.out.println("going to insert + "+orderlist.substring(0, orderlist.length()).toString() );

orderlist.delete(0, orderlist.length());
                 //   } catch (SQLException ex) {}
                   P = null;
                    ordersMade += 1;
                    listener.ordersNum(ordersMade);
                    OrderVector.removeAllElements();

                } else {
                    listener.PostMsg("Kitchen not ready " + name + "!!");
                }
            }
        }

    }

    public synchronized void listofclients() {
        String[] names = perUser.clients();
        listener.ListClient(names);

    }

    public synchronized void listofclientsoff() {
        String[] names = perUser.clientsdisconnected();
        listener.ListClientoff(names);
    }

    public static String unID() {
        char[] buf = new char[Num_Chars];
        for (int i = 0; i < buf.length; i++) {
            buf[i] = chars.charAt(r.nextInt(chars.length()));
        }
        return new String(buf);
    }
}
